﻿#region 命名空间

using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using AutoMapper;
using Sharp.Infrastructure;

#pragma warning disable 618

#endregion


// ReSharper disable once CheckNamespace
namespace System
{
    [DebuggerStepThrough]
    public static class MapperExtension
    {
        public static TDestination To<TDestination>(this object source)
        {
            if (source == null)
            {
                return default(TDestination);
            }
           
            return Mapper.Map<TDestination>(source);
        }
        public static TDestination To<TSource, TDestination>(this TSource source, TDestination destination)
            where TSource : class
            where TDestination : class
        {
            
            return Mapper.Map<TDestination>(source);
        }

        public static IEnumerable<TDestination> To<TSource, TDestination>(this IEnumerable<TSource> source)
        { 

            return source.Select(x => Mapper.Map<TDestination>(x));
        }


        /// <summary>
        /// 转换DTO模型
        /// </summary>
        /// <typeparam name="TSource"></typeparam>
        /// <typeparam name="TDestination"></typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public static PagedResult<TDestination> ToDTO<TSource, TDestination>(this PagedResult<TSource> input)
            where TSource : class
            where TDestination : class
        { 
            var newResult = new PagedResult<TDestination>();
            newResult.PageSize = input.PageSize;
            newResult.PageNumber = input.PageNumber;
            newResult.TotalRecords = input.TotalRecords;

            newResult.Data = Mapper.Map<List<TDestination>>(input.Data);

            return newResult;
        }

        /// <summary>
        /// 转换DTO模型
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TDestination">目标类型</typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public static PagedResult<TDestination> To<TSource, TDestination>(this PagedResult<TSource> input)
            where TDestination : class
        {
            var newResult = new PagedResult<TDestination>
            {
                PageSize = input.PageSize,
                PageNumber = input.PageNumber,
                TotalRecords = input.TotalRecords,
                Data = input.Data.Select(x => Mapper.Map<TDestination>(x)).ToList()
            };
            #if DEBUG
            if (input.Data.Count != newResult.Data.Count)
            {
                throw new NotImplementedException("转换失败。");
            }
            #endif
 
            return newResult;
        }

        /// <summary>
        /// 转换DTO模型
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TDestination">目标类型</typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public static Result<IEnumerable<TDestination>> To<TSource, TDestination>(this Result<IEnumerable<TSource>> input)
        {
            var res = new Result<IEnumerable<TDestination>>
            {
                Data = input.Data.To<List<TDestination>>(),
                Err = input.Err,
                Id = input.Id,
                Message = input.Message
            };

            return res;
        }
        /// <summary>
        /// 转换DTO模型
        /// </summary>
        /// <typeparam name="TSource">源类型</typeparam>
        /// <typeparam name="TDestination">目标类型</typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public static Result<TDestination> To<TSource, TDestination>(this Result<TSource> input)
        {
            var res = new Result<TDestination>
            {
                Data = input.Data.To<TDestination>(),
                Err = input.Err,
                Id = input.Id,
                Message = input.Message
            };

            return res;
        }
    }

    /// <summary>
    /// 填充那些常见导航属性
    /// </summary>
    [Flags]
    public enum FillData
    {
        CheckInUser = 0,
        ModifiedUser = 1
    }
}